home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / xulrunner / python / BitTorrent / bencode.py < prev    next >
Encoding:
Python Source  |  2007-11-12  |  7.0 KB  |  313 lines

  1. # Written by Petru Paler
  2. # see LICENSE.txt for license information
  3.  
  4. def decode_int(x, f):
  5.     f += 1
  6.     newf = x.index('e', f)
  7.     try:
  8.         n = int(x[f:newf])
  9.     except (OverflowError, ValueError):
  10.         n = long(x[f:newf])
  11.     if x[f] == '-':
  12.         if x[f + 1] == '0':
  13.             raise ValueError
  14.     elif x[f] == '0' and newf != f+1:
  15.         raise ValueError
  16.     return (n, newf+1)
  17.  
  18. def decode_string(x, f):
  19.     colon = x.index(':', f)
  20.     try:
  21.         n = int(x[f:colon])
  22.     except (OverflowError, ValueError):
  23.         n = long(x[f:colon])
  24.     if x[f] == '0' and colon != f+1:
  25.         raise ValueError
  26.     colon += 1
  27.     return (x[colon:colon+n], colon+n)
  28.  
  29. def decode_list(x, f):
  30.     r, f = [], f+1
  31.     while x[f] != 'e':
  32.         v, f = decode_func[x[f]](x, f)
  33.         r.append(v)
  34.     return (r, f + 1)
  35.  
  36. def decode_dict(x, f):
  37.     r, f = {}, f+1
  38.     lastkey = None
  39.     while x[f] != 'e':
  40.         k, f = decode_string(x, f)
  41.         if lastkey >= k:
  42.             raise ValueError
  43.         lastkey = k
  44.         r[k], f = decode_func[x[f]](x, f)
  45.     return (r, f + 1)
  46.  
  47. decode_func = {}
  48. decode_func['l'] = decode_list
  49. decode_func['d'] = decode_dict
  50. decode_func['i'] = decode_int
  51. decode_func['0'] = decode_string
  52. decode_func['1'] = decode_string
  53. decode_func['2'] = decode_string
  54. decode_func['3'] = decode_string
  55. decode_func['4'] = decode_string
  56. decode_func['5'] = decode_string
  57. decode_func['6'] = decode_string
  58. decode_func['7'] = decode_string
  59. decode_func['8'] = decode_string
  60. decode_func['9'] = decode_string
  61.  
  62. def bdecode(x):
  63.     try:
  64.         r, l = decode_func[x[0]](x, 0)
  65.     except (IndexError, KeyError):
  66.         raise ValueError
  67.     if l != len(x):
  68.         raise ValueError
  69.     return r
  70.  
  71. def test_bdecode():
  72.     try:
  73.         bdecode('0:0:')
  74.         assert 0
  75.     except ValueError:
  76.         pass
  77.     try:
  78.         bdecode('ie')
  79.         assert 0
  80.     except ValueError:
  81.         pass
  82.     try:
  83.         bdecode('i341foo382e')
  84.         assert 0
  85.     except ValueError:
  86.         pass
  87.     assert bdecode('i4e') == 4L
  88.     assert bdecode('i0e') == 0L
  89.     assert bdecode('i123456789e') == 123456789L
  90.     assert bdecode('i-10e') == -10L
  91.     try:
  92.         bdecode('i-0e')
  93.         assert 0
  94.     except ValueError:
  95.         pass
  96.     try:
  97.         bdecode('i123')
  98.         assert 0
  99.     except ValueError:
  100.         pass
  101.     try:
  102.         bdecode('')
  103.         assert 0
  104.     except ValueError:
  105.         pass
  106.     try:
  107.         bdecode('i6easd')
  108.         assert 0
  109.     except ValueError:
  110.         pass
  111.     try:
  112.         bdecode('35208734823ljdahflajhdf')
  113.         assert 0
  114.     except ValueError:
  115.         pass
  116.     try:
  117.         bdecode('2:abfdjslhfld')
  118.         assert 0
  119.     except ValueError:
  120.         pass
  121.     assert bdecode('0:') == ''
  122.     assert bdecode('3:abc') == 'abc'
  123.     assert bdecode('10:1234567890') == '1234567890'
  124.     try:
  125.         bdecode('02:xy')
  126.         assert 0
  127.     except ValueError:
  128.         pass
  129.     try:
  130.         bdecode('l')
  131.         assert 0
  132.     except ValueError:
  133.         pass
  134.     assert bdecode('le') == []
  135.     try:
  136.         bdecode('leanfdldjfh')
  137.         assert 0
  138.     except ValueError:
  139.         pass
  140.     assert bdecode('l0:0:0:e') == ['', '', '']
  141.     try:
  142.         bdecode('relwjhrlewjh')
  143.         assert 0
  144.     except ValueError:
  145.         pass
  146.     assert bdecode('li1ei2ei3ee') == [1, 2, 3]
  147.     assert bdecode('l3:asd2:xye') == ['asd', 'xy']
  148.     assert bdecode('ll5:Alice3:Bobeli2ei3eee') == [['Alice', 'Bob'], [2, 3]]
  149.     try:
  150.         bdecode('d')
  151.         assert 0
  152.     except ValueError:
  153.         pass
  154.     try:
  155.         bdecode('defoobar')
  156.         assert 0
  157.     except ValueError:
  158.         pass
  159.     assert bdecode('de') == {}
  160.     assert bdecode('d3:agei25e4:eyes4:bluee') == {'age': 25, 'eyes': 'blue'}
  161.     assert bdecode('d8:spam.mp3d6:author5:Alice6:lengthi100000eee') == {'spam.mp3': {'author': 'Alice', 'length': 100000}}
  162.     try:
  163.         bdecode('d3:fooe')
  164.         assert 0
  165.     except ValueError:
  166.         pass
  167.     try:
  168.         bdecode('di1e0:e')
  169.         assert 0
  170.     except ValueError:
  171.         pass
  172.     try:
  173.         bdecode('d1:b0:1:a0:e')
  174.         assert 0
  175.     except ValueError:
  176.         pass
  177.     try:
  178.         bdecode('d1:a0:1:a0:e')
  179.         assert 0
  180.     except ValueError:
  181.         pass
  182.     try:
  183.         bdecode('i03e')
  184.         assert 0
  185.     except ValueError:
  186.         pass
  187.     try:
  188.         bdecode('l01:ae')
  189.         assert 0
  190.     except ValueError:
  191.         pass
  192.     try:
  193.         bdecode('9999:x')
  194.         assert 0
  195.     except ValueError:
  196.         pass
  197.     try:
  198.         bdecode('l0:')
  199.         assert 0
  200.     except ValueError:
  201.         pass
  202.     try:
  203.         bdecode('d0:0:')
  204.         assert 0
  205.     except ValueError:
  206.         pass
  207.     try:
  208.         bdecode('d0:')
  209.         assert 0
  210.     except ValueError:
  211.         pass
  212.     try:
  213.         bdecode('00:')
  214.         assert 0
  215.     except ValueError:
  216.         pass
  217.     try:
  218.         bdecode('l-3:e')
  219.         assert 0
  220.     except ValueError:
  221.         pass
  222.     try:
  223.         bdecode('i-03e')
  224.         assert 0
  225.     except ValueError:
  226.         pass
  227.     bdecode('d0:i3ee')
  228.  
  229. from types import UnicodeType, StringType, IntType, LongType, DictType, ListType, TupleType
  230.  
  231. class Bencached(object):
  232.     __slots__ = ['bencoded']
  233.  
  234.     def __init__(self, s):
  235.         self.bencoded = s
  236.  
  237. def encode_bencached(x,r):
  238.     r.append(x.bencoded)
  239.  
  240. def encode_int(x, r):
  241.     r.extend(('i', str(x), 'e'))
  242.  
  243. def encode_string(x, r):
  244.     r.extend((str(len(x)), ':', x))
  245.  
  246. def encode_unicode(x, r):
  247.     x = x.encode('utf-8')
  248.     return encode_string(x,r)
  249.  
  250. def encode_list(x, r):
  251.     r.append('l')
  252.     for i in x:
  253.         encode_func[type(i)](i, r)
  254.     r.append('e')
  255.  
  256. def encode_dict(x,r):
  257.     r.append('d')
  258.     ilist = x.items()
  259.     ilist.sort()
  260.     for k, v in ilist:
  261.         encode_func[type(k)](k, r)
  262.         encode_func[type(v)](v, r)
  263.     r.append('e')
  264.  
  265. encode_func = {}
  266. encode_func[type(Bencached(0))] = encode_bencached
  267. encode_func[IntType] = encode_int
  268. encode_func[LongType] = encode_int
  269. encode_func[StringType] = encode_string
  270. encode_func[UnicodeType] = encode_unicode
  271. encode_func[ListType] = encode_list
  272. encode_func[TupleType] = encode_list
  273. encode_func[DictType] = encode_dict
  274.  
  275. try:
  276.     from types import BooleanType
  277.     encode_func[BooleanType] = encode_int
  278. except ImportError:
  279.     pass
  280.  
  281. def bencode(x):
  282.     r = []
  283.     encode_func[type(x)](x, r)
  284.     return ''.join(r)
  285.  
  286. def test_bencode():
  287.     assert bencode(4) == 'i4e'
  288.     assert bencode(0) == 'i0e'
  289.     assert bencode(-10) == 'i-10e'
  290.     assert bencode(12345678901234567890L) == 'i12345678901234567890e'
  291.     assert bencode('') == '0:'
  292.     assert bencode('abc') == '3:abc'
  293.     assert bencode('1234567890') == '10:1234567890'
  294.     assert bencode([]) == 'le'
  295.     assert bencode([1, 2, 3]) == 'li1ei2ei3ee'
  296.     assert bencode([['Alice', 'Bob'], [2, 3]]) == 'll5:Alice3:Bobeli2ei3eee'
  297.     assert bencode({}) == 'de'
  298.     assert bencode({'age': 25, 'eyes': 'blue'}) == 'd3:agei25e4:eyes4:bluee'
  299.     assert bencode({'spam.mp3': {'author': 'Alice', 'length': 100000}}) == 'd8:spam.mp3d6:author5:Alice6:lengthi100000eee'
  300.     assert bencode(Bencached(bencode(3))) == 'i3e'
  301.     try:
  302.         bencode({1: 'foo'})
  303.     except TypeError:
  304.         return
  305.     assert 0
  306.  
  307. try:
  308.     import psyco
  309.     psyco.bind(bdecode)
  310.     psyco.bind(bencode)
  311. except ImportError:
  312.     pass
  313.